package com.bwie.auth.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.bwie.auth.remote.RemoteSysUser;
import com.bwie.auth.service.AuthService;
import com.bwie.common.constants.Constants;
import com.bwie.common.constants.JwtConstants;
import com.bwie.common.constants.TokenConstants;
import com.bwie.common.domain.SysUser;
import com.bwie.common.domain.request.LoginReq;
import com.bwie.common.domain.response.JwtRes;
import com.bwie.common.exception.BizException;
import com.bwie.common.result.Result;
import com.bwie.common.utils.JwtUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@Service
public class AuthServiceImpl implements AuthService {
    @Autowired
    private RemoteSysUser remoteSysUser;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private HttpServletRequest request;

    /**
     * 登录
     * @param loginReq
     * @return
     */
    @Override
    public JwtRes login(LoginReq loginReq) {
        //远程调用根据用户名获取用户信息方法
        Result<SysUser> result = remoteSysUser.selectOneByName(loginReq.getUsername());
        //熔断
        if (result.getCode() == Constants.ERROR){
            throw new BizException("根据用户名获取用户信息失败");
        }
        SysUser sysUser = result.getData();

        //判断用户是否存在
        if (sysUser==null){
            throw new BizException("用户名不存在，请先注册");
        }

        //判断密码是否正确
        if (!loginReq.getPassWord().equals(sysUser.getPassWord())){
            throw new BizException("密码错误，请重试");
        }

        //确保token的唯一性
        HashMap<String, Object> claims = new HashMap<>();
        String userKey = UUID.randomUUID().toString().replace("-", "");
        claims.put(JwtConstants.USER_KEY,userKey);
        String token = JwtUtils.createToken(claims);

        //将用户信息存入redis
        redisTemplate.opsForValue().set(TokenConstants.LOGIN_TOKEN_KEY+userKey, JSONObject.toJSONString(sysUser),20, TimeUnit.MINUTES);

        //返回令牌
        JwtRes jwtRes = new JwtRes();
        jwtRes.setExpireTime("20MIN");
        jwtRes.setToken(token);
        return jwtRes;
    }

    /**
     * 获取登录用户信息
     * @return
     */
    @Override
    public SysUser userInfo() {
        String token = request.getHeader(TokenConstants.TOKEN);
        String userKey = JwtUtils.getUserKey(token);
        String sysUserStr = redisTemplate.opsForValue().get(TokenConstants.LOGIN_TOKEN_KEY + userKey);
        SysUser sysUser = JSONObject.parseObject(sysUserStr, SysUser.class);
        return sysUser;
    }
}
